package com.qf.controller;

import com.qf.pojo.DtsCategory;
import com.qf.pojo.DtsGoods;
import com.qf.pojo.DtsOrder;
import com.qf.pojo.DtsUser;
import com.qf.service.DtsCategoryService;
import com.qf.service.DtsGoodsService;
import com.qf.service.DtsOrderService;
import com.qf.service.DtsUserService;
import com.qf.util.ResponseUtil;
import com.qf.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;

/**
 * 首页相关数据查询
 *
 * @author lixu
 */
@RestController
@RequestMapping("/admin/dashboard")
@CrossOrigin
@SuppressWarnings("all")
public class DashboardController {

    @Autowired
    private DtsGoodsService dtsGoodsService;
    @Autowired
    private DtsCategoryService dtsCategoryService;
    @Autowired
    private DtsOrderService dtsOrderService;
    @Autowired
    private DtsUserService dtsUserService;

    private static final int STATIS_DAYS_RANG = 30;// 统计的天数范围，一个月数据

    /**
     * - 首页统计用户数, 商品数, 库存货品数,订单数地址 : http://localhost:8083/admin/dashboard
     * - GET请求
     * - 下行数据 :
     * - goodsTotal : 商品数量, userTotal : 用户数量 , productTotal : 货品数量 , orderTotal : 订单数量
     * <p>
     * <p>
     * {
     * "errno":0,
     * "data":{
     * "goodsTotal":426,
     * "userTotal":197,
     * "productTotal":8939,
     * "orderTotal":107
     * },
     * "errmsg":"成功"
     * }
     * <p>
     * 编译阶段： 速度是慢的
     */
    @GetMapping
    public Object dashboard() {


        Map data = new HashMap<>();
        Long goodsTotal = dtsGoodsService.findCount();
        data.put("goodsTotal", goodsTotal);
        data.put("userTotal", 197);
        data.put("productTotal", 8939);
        data.put("orderTotal", 107);

        return ResponseUtil.ok(data);
    }

    /**
     * - 首页数据可视化图表地址 : http://localhost:8083/admin/dashboard/chart
     * <p>
     * - GET请求
     * <p>
     * - 下行数据 :
     * <p>
     * - categorySell : 商品分类  和对应分类的销售额
     * orderAmts : 日期和对应的订单总额, 订单笔数
     * userOrderCnt : 日期对应的用户数和订单数
     */
    @GetMapping("/chart")
    public Object chart() {
        //1:categorySell : 商品分类和对应分类的销售额
        CategorySellVo categorySellVo = dtsCategoryService.findCategorySellVo();
        //2:  日期和对应的订单总额, 订单笔数  select count(1),sum(actual_price)
        List<DayStatis> dayStatisListByOrder = dtsOrderService.findOrderAmtsVo(STATIS_DAYS_RANG);
        OrderAmtsVo orderAmtsVo = new OrderAmtsVo();
        //订单数量 数组
        Integer[] orderCntData = dayStatisListByOrder.stream().map(DayStatis::getCnts)
                .toArray((value -> new Integer[dayStatisListByOrder.size()]));
        orderAmtsVo.setOrderCntData(orderCntData);
        //订单金额 数组
        orderAmtsVo.setOrderAmtData(dayStatisListByOrder.stream().map(DayStatis::getAmts).
                toArray((value -> new BigDecimal[dayStatisListByOrder.size()])));
        //日期的数组
        orderAmtsVo.setDayData(dayStatisListByOrder.stream().map(DayStatis::getDayStr)
                .toArray((value -> new String[dayStatisListByOrder.size()])));

        //3:userOrderCnt : 日期对应的用户数和订单笔数
        List<DayStatis> dayStatisListByUser = dtsUserService.findUserOrderCnt(STATIS_DAYS_RANG);
        UserOrderCntVo userOrderCntVo = new UserOrderCntVo();
        //用户增量
        userOrderCntVo.setUserCnt(dayStatisListByUser.stream().mapToInt(DayStatis::getCnts).toArray());
        //日期数组
        userOrderCntVo.setDayData(dayStatisListByUser.stream().map(DayStatis::getDayStr)
                .toArray(value -> new String[dayStatisListByUser.size()]));
        //3.1:缺少订单笔数
        userOrderCntVo = mergeOrderAmtsVoAndUserOrderCntVo(dayStatisListByOrder, dayStatisListByUser);
        Map data = new HashMap<>();
        data.put("categorySell", categorySellVo);
        data.put("orderAmts", orderAmtsVo);
        data.put("userOrderCnt", userOrderCntVo);
        return ResponseUtil.ok(data);

    }

    /**
     * 合并 日期对应的用户数及订单笔数
     *
     * @return
     */
    private UserOrderCntVo mergeOrderAmtsVoAndUserOrderCntVo(
            List<DayStatis> dayStatisListByOrder, List<DayStatis> dayStatisListByUser) {

        UserOrderCntVo userOrderCntVo = new UserOrderCntVo();
        //逻辑开发
        ////完整的 （最全的）
        Set<String> dayData = new HashSet<>();
        //1:关于订单笔数的日期数组   缺少 10 ， 22 ，23 。。。
        for (DayStatis day : dayStatisListByOrder) {
            dayData.add(day.getDayStr());
        }
        //2:关于用户数的日期数组    缺少31号
        for (DayStatis day : dayStatisListByUser) {
            dayData.add(day.getDayStr());
        }
        //3:将完整的日期时间设置到了 UserOrderCntVo
        ArrayList<String> list = new ArrayList<>(dayData);
        Collections.sort(list);//由小到大  日期  同学们由于非常强大 由大到小也是可以的
        String[] array = list.toArray(new String[list.size()]);
        userOrderCntVo.setDayData(array);
        //4:使用完整的日期时间 找到对应的用户数 及订单笔数

        Map<String, Integer> mapByOrder = dayStatisListByOrder.stream()
                .collect(Collectors.toMap(DayStatis::getDayStr, DayStatis::getCnts));
        int[] cntsO = list.stream().mapToInt(dayDatum -> {
            Integer cntsByOrder = mapByOrder.get(dayDatum);
            if (null == cntsByOrder) {
                cntsByOrder = 0;
            }
            return cntsByOrder;
        }).toArray();
        ///////////////////
        Map<String, Integer> mapByUser = dayStatisListByUser.stream()
                .collect(Collectors.toMap(DayStatis::getDayStr, DayStatis::getCnts));
        int[] cntsU = list.stream().mapToInt(dayDatum -> {
            Integer cntsByUser = mapByUser.get(dayDatum);
            if (null == cntsByUser) {
                cntsByUser = 0;
            }
            return cntsByUser;
        }).toArray();
        userOrderCntVo.setOrderCnt(cntsO);
        userOrderCntVo.setUserCnt(cntsU);
        return userOrderCntVo;

    }
}
